home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
language
/
asxsrc.arc
/
M05MCH.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-08-25
|
4KB
|
271 lines
/* m05mch.c */
/*
* (C) Copyright 1989
* All Rights Reserved
*
* Alan R. Baldwin
* 721 Berkeley St.
* Kent, Ohio 44240
*/
#include <stdio.h>
#include <setjmp.h>
#include "asm.h"
#include "6805.h"
#define NB 256
int *bp;
int bm;
int bb[NB];
struct sdp sdp[] = {
NULL
};
/*
* Process a machine op.
*/
VOID
machine(mp)
struct mne *mp;
{
register op, t1, t2, type;
struct expr e1, e2, e3;
addr_t espv;
struct area *espa;
char id[NCPS];
int flag, v1;
op = mp->m_valu;
type = mp->m_type;
switch (type) {
case S_SDP:
espa = NULL;
if (more()) {
getid(id, -1);
espa = alookup(id);
if ( espa == NULL) {
err('u');
}
}
if (espa) {
sdp->s_area = espa;
} else {
sdp->s_area = dot->s_area;
}
lmode = SLIST;
break;
case S_INH:
outab(op);
break;
case S_BRA:
expr(&e1, 0);
v1 = e1.e_addr - dot->s_addr - 2;
if ((v1 < -128) || (v1 > 127))
aerr();
if (e1.e_base.e_ap != dot->s_area)
rerr();
outab(op);
outab(v1);
break;
case S_TYP1:
t1 = addr(&e1);
espv = e1.e_addr;
espa = e1.e_base.e_ap;
if (t1 == S_A) {
outab(op+0x10);
break;
}
if (t1 == S_X) {
outab(op+0x20);
break;
}
if (t1 == S_DIR) {
outab(op);
outrb(&e1, 0);
break;
}
if (t1 == S_IX) {
outab(op+0x40);
break;
}
if (t1 == S_DIRX) {
outab(op+0x30);
outrb(&e1, 0);
break;
}
aerr();
break;
case S_TYP2:
t1 = addr(&e1);
espv = e1.e_addr;
espa = e1.e_base.e_ap;
if (t1 == S_IMMED) {
if ((op == 0xA7) ||
(op == 0xAC) ||
(op == 0xAF))
aerr();
outab(op);
outrb(&e1, 0);
break;
}
if (t1 == S_DIR) {
outab(op+0x10);
outrb(&e1, 0);
break;
}
if (t1 == S_EXT) {
outab(op+0x20);
outrw(&e1, 0);
break;
}
if (t1 == S_IX) {
outab(op+0x50);
break;
}
if (t1 == S_DIRX) {
outab(op+0x40);
outrb(&e1, 0);
break;
}
if (t1 == S_INDX) {
if (pass == 0) {
dot->s_addr += 3;
} else
if (e1.e_flag ||
(espa && espa != dot->s_area)) {
outab(op+0x30);
outrw(&e1, 0);
} else
if (pass == 1) {
if (e1.e_addr >= dot->s_addr)
e1.e_addr -= fuzz;
flag = 0;
if (espv & ~0xFF)
++flag;
if (setbit(flag)) {
dot->s_addr += 3;
} else {
dot->s_addr += 2;
}
} else {
if (getbit()) {
outab(op+0x30);
outrw(&e1, 0);
} else {
outab(op+0x40);
outrb(&e1, 0);
}
}
break;
}
aerr();
break;
case S_TYP3:
case S_TYP4:
t1 = addr(&e1);
espv = e1.e_addr;
if (t1 != S_IMMED)
aerr();
if (espv & ~0x07)
aerr();
e1.e_addr = op + 2*(espv&0x07);
comma();
t2 = addr(&e2);
if (t2 != S_DIR)
aerr();
espa = e2.e_base.e_ap;
if (espa && espa != sdp->s_area)
rerr();
if (type == S_TYP4) {
expr(&e3, 0);
v1 = e3.e_addr - dot->s_addr - 3;
if ((v1 < -128) || (v1 > 127))
aerr();
if (e3.e_base.e_ap != dot->s_area)
rerr();
}
outrb(&e1, 0);
outrb(&e2, 0);
if (type == S_TYP4)
outab(v1);
break;
default:
err('o');
}
}
/*
* The next character must be a
* comma.
*/
VOID
comma()
{
if (getnb() != ',')
qerr();
}
/*
* Machine specific initialization.
* Set up the bit table.
* Reset direct page.
*/
VOID
minit()
{
bp = bb;
bm = 1;
sdp->s_area = dot->s_area;
}
/*
* Store `b' in the next slot of the bit table.
* If no room, force the longer form of the offset.
*/
int
setbit(b)
{
if (bp >= &bb[NB])
return(1);
if (b)
*bp |= bm;
bm <<= 1;
if (bm == 0) {
bm = 1;
++bp;
}
return(b);
}
/*
* Get the next bit from the bit table.
* If none left, return a `1'.
* This will force the longer form of the offset.
*/
int
getbit()
{
register f;
if (bp >= &bb[NB])
return (1);
f = *bp & bm;
bm <<= 1;
if (bm == 0) {
bm = 1;
++bp;
}
return (f);
}